﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using TaskLib.Scheduling;
using TaskLib.UI;

namespace WindowsFormsTester
{
    public partial class FormMain : Form, IRegulator
    {
        private readonly TaskSchedulerBase m_taskScheduler = new TaskSchedulerForPriority(urgentCoreCount: 1);

        private readonly List<CustomTask> m_tasks = new List<CustomTask>();

        public FormMain()
        {
            InitializeComponent();
            m_taskScheduler.Register(this);
        }

        public void TaskStatusChanged(Task task)
        {
            this.BeginInvoke((MethodInvoker)delegate()
            {
                if (task is CustomTask customTask)
                {
                    int index = -1;
                    for (int i = 0; i < m_tasks.Count; i++)
                    {
                        if (m_tasks[i].TaskId == customTask.TaskId)
                        {
                            index = i;
                        }
                    }
                    if (index > -1)
                    {
                        if (customTask.IsCompleted)
                        {
                            listViewTask.Items[index].SubItems[5].Text = customTask.CompletedTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
                        }
                        else
                        {
                            listViewTask.Items[index].SubItems[4].Text = customTask.StartTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
                        }
                    }
                }
            });
        }

        private void BtnAddNormalTask_Click(object sender, EventArgs e)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            CustomTask task = new CustomTask(() =>
            {
                double sum = 0;
                for (int i = 1; i < 100000 * 10000; i++)
                {
                    sum += i;
                    sum /= i;
                }
                Trace.WriteLine(String.Format("{0}, SUM: {1}", Thread.CurrentThread.ManagedThreadId, sum));
            }, cts.Token)
            {
                TaskId = Guid.NewGuid().ToString(),
                Priority = TaskPriority.Normal,
                CreateTime = DateTime.Now
            };
            AddTask(task);

            task.Start(m_taskScheduler);
            m_tasks.Add(task);
        }

        private void AddTask(CustomTask task)
        {
            listViewTask.SuspendLayout();
            ListViewItem item = listViewTask.Items.Add((listViewTask.Items.Count + 1).ToString());
            item.SubItems.Add(task.TaskId);
            item.SubItems.Add(task.Priority.ToString());
            item.SubItems.Add(task.CreateTime.ToString("yyyy-MM-dd HH:mm:ss.fff"));
            item.SubItems.Add(String.Empty);
            item.SubItems.Add(String.Empty);
            listViewTask.ResumeLayout();
        }

        private void BtnAddUrgentTask_Click(object sender, EventArgs e)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            CustomTask task = new CustomTask(() =>
            {
                double sum = 0;
                for (int i = 1; i < 100000 * 10000; i++)
                {
                    sum += i;
                    sum /= i;
                }
                Trace.WriteLine(String.Format("urgent {0}, SUM: {1}", Thread.CurrentThread.ManagedThreadId, sum));
            }, cts.Token)
            {
                TaskId = Guid.NewGuid().ToString(),
                Priority = TaskPriority.Urgent,
                CreateTime = DateTime.Now
            };
            AddTask(task);

            task.Start(m_taskScheduler);
            m_tasks.Add(task);
        }
    }
}
